home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 November
/
EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso
/
earcd
/
ead
/
ead11.dms
/
ead11.adf
/
Listati
/
Ing.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-01-08
|
8KB
|
355 lines
/* :ts=8 bk=0
*******************************************************************
* Ing.c - Un divertimento da Workbench - Scritto da Leo L. Schwab *
* Programma di pubblico dominio, si prega solo di lasciare i nomi *
**** Tradotto ed adattato a Aztec C V3.6 da Luigi R. Callegari ****
********** Compilazione: cc Ing +L (interi a 32 bit) ***********
********** Linking : ln -lm32 -lc32 Ing ***********
******************************************************************/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <math.h>
#define DEPTH 2
extern void *OpenLibrary(), *OpenWindow(), *OpenScreen(), *AllocRaster(),
*GetMsg(), *malloc();
extern long VBeamPos();
struct NewScreen scrdef = {
0, 0, 0, 0, DEPTH, /* Dimensioni fissate dopo */
0, 1,
HIRES,
CUSTOMSCREEN,
NULL,
NULL, /* Titolo fissato dopo */
NULL, NULL
};
struct NewWindow windef = {
0, 30, 150, 10,
-1, -1,
CLOSEWINDOW,
WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|SMART_REFRESH|ACTIVATE,
NULL, NULL,
(UBYTE *)"Ing!",
NULL, NULL,
0, 0, 0, 0,
WBENCHSCREEN
};
struct wlist {
struct wlist *next, *prev;
struct BitMap bitmap;
long sizx, sizy;
int maxx, maxy;
int x, y, dx, dy;
int maxdy;
};
struct Screen *scr, *wb;
struct Window *win;
struct BitMap *bm1, bm2, barmap;
struct wlist *listbase;
void *IntuitionBase, *GfxBase;
void main ()
{
struct Window *wbwin;
struct ViewPort *svp;
register struct BitMap *abm;
struct BitMap *wbbm, **vbm;
register struct wlist *this = NULL;
struct wlist *new;
long wide, high, barhigh, wbhigh;
int i;
void *msg;
openstuff ();
rnd ((short) -VBeamPos());
wb = win -> WScreen; /* Workbench screen */
wbbm = wb -> RastPort.BitMap;
scrdef.LeftEdge = wb -> LeftEdge;
scrdef.TopEdge = wb -> TopEdge;
scrdef.Width = wb -> Width;
scrdef.Height = wbhigh = wb -> Height;
/* Scandisce tutte le finestre nel Workbench */
for (wbwin = wb -> FirstWindow; wbwin; wbwin = wbwin -> NextWindow) {
if (wbwin->Flags & BACKDROP && wbwin->Flags & WBENCHWINDOW) {
scrdef.DefaultTitle = wbwin -> ScreenTitle;
continue;
}
if (wbwin -> Height > wbhigh-21)
continue; /* troppo piccola, lasciamo */
if (wbwin -> Width > wb->Width - 40)
continue; /* troppo larga, lasciamo */
/* Allocate new entry in list */
if (!(new = malloc (sizeof (*new))))
die ("malloc() non funziona!");
new -> prev = this;
new -> next = NULL;
if (this)
this -> next = new;
listbase = new;
/* Legge informazioni necessarie */
wide = new -> sizx = wbwin -> Width;
high = new -> sizy = wbwin -> Height;
new -> maxx = wb -> Width - wide;
new -> maxy = wb -> Height - high;
new -> x = wbwin -> LeftEdge;
new -> y = wbwin -> TopEdge;
new -> dx = new -> dy = 0;
/* Calcolo della max velocita' verticale iniziale.
Mi ci e' voluto un sacco di tempo per calcolare questa
formula. Qui a Princeton studio altro...*/
new -> maxdy = sqrt (2 * new->maxy + 0.25) - 0.5 + 1.0;
/* Crea bitmap e vi copia la finestra */
InitBitMap (&new -> bitmap, (long) DEPTH, wide, high);
for (i=0; i<DEPTH; i++)
if (!(new -> bitmap.Planes[i] = AllocRaster (wide, high)))
die ("AllocRaster() non funziona!");
WindowToFront (wbwin); /* WindowToFront() non funge */
Delay (5L); /* subito, quindi aspettiamo */
BltBitMap
(wbbm, (long) wbwin -> LeftEdge, (long) wbwin -> TopEdge,
&new -> bitmap, 0L, 0L,
wide, high, 0xC0L, 0xffL, NULL);
this = new;
}
/* Letto e copiato tutte le finestre. Ora c'e' il bello */
scr = OpenScreen (&scrdef); /* Clona il WorkBench */
bm1 = scr -> ViewPort.RasInfo -> BitMap;
svp = &scr -> ViewPort;
/* Crea secondo insieme di bitplanes per doppio buffer */
wide = wb -> Width;
InitBitMap (&bm2, (long) DEPTH, wide, wbhigh);
for (i=0; i<DEPTH; i++)
if (!(bm2.Planes[i] = AllocRaster (wide, wbhigh)))
die ("AllocRaster() 2 ha fallito!");
BltBitMap
(bm1, 0L, 0L, &bm2, 0L, 0L, wide, wbhigh, 0xc0L, 0xffL, NULL);
/* Crea bitmap privata per conservare barra di titolo schermo */
barhigh = wb -> BarHeight;
InitBitMap (&barmap, (long) DEPTH, wide, barhigh);
for (i=0; i<DEPTH; i++)
if (!(barmap.Planes[i] = AllocRaster (wide, barhigh)))
die ("AllocRaster() 3 ha fallito!");
BltBitMap
(bm1, 0L, 0L, &barmap, 0L, 0L, wide, barhigh, 0xc0L, 0xffL, NULL);
i = 0;
vbm = &scr -> ViewPort.RasInfo -> BitMap;
abm = &bm2;
while (1) {
/* Copia barra schermo */
BltBitMap (&barmap, 0L, 0L,
abm, 0L, 0L,
wide, barhigh, 0xc0L, 0xffL, NULL);
/* Pulisce resto schermo */
BltBitMap (abm, 0L, 0L,
abm, 0L, barhigh,
wide, wbhigh-barhigh, 0L, 0xffL, NULL);
/* Copia finestre scandite all'indietro */
for (this = listbase; this; this = this -> prev) {
if ((this -> x += this -> dx) > this -> maxx) {
this -> x = this->maxx * 2 - this->x;
this -> dx = -this -> dx;
} else if (this -> x < 0) {
this -> x = -this -> x;
this -> dx = -this -> dx;
}
if ((this -> y += this -> dy) > this -> maxy) {
this -> y = this -> maxy;
this -> dy = -rnd (this->maxdy - 4) - 4;
this -> dx = rnd (31) - 15;
} else
this -> dy++;
/* Copia immagine finestra */
BltBitMap
(&this -> bitmap, 0L, 0L,
abm, (long) this -> x, (long) this -> y,
this -> sizx, this -> sizy, 0xc0L, 0xffL, NULL);
}
/* Questa e' la parte intrigante. Ho cercato di mantenere
al minimo lo hashing, ma in certe fasi lunari e' sempre
inevitabile */
Forbid ();
if (i) { /* Ping */
*vbm = bm1;
abm = &bm2;
} else { /* Pong */
*vbm = &bm2;
abm = bm1;
}
i = !i;
/* Sorpresa! Intuition se ne frega di questo! */
ScrollVPort (svp);
Permit ();
if (msg = GetMsg (win -> UserPort)) {
ReplyMsg (msg);
break;
}
WaitTOF ();
}
/* Rimetti l'originale */
Forbid ();
*vbm = bm1;
ScrollVPort (svp); /* Ping! */
Permit ();
closestuff ();
}
openstuff ()
{
if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) {
printf ("Intuition dov'e'???.\n");
exit (100);
}
if (!(GfxBase = OpenLibrary ("graphics.library", 0L))) {
printf ("Le routines grafiche???\n");
closestuff ();
exit (100);
}
if (!(win = OpenWindow (&windef))) {
printf ("La finestra???\n");
closestuff ();
exit (100);
}
}
die (str)
char *str;
{
puts (str);
closestuff ();
exit (100);
}
closestuff ()
{
register int i;
for (i=0; i<DEPTH; i++) {
if (barmap.Planes[i])
FreeRaster (barmap.Planes[i],
(long) wb->Width, (long) wb->BarHeight);
if (bm2.Planes[i])
FreeRaster (bm2.Planes[i],
(long) wb->Width, (long) wb->Height);
}
if (listbase) freelist ();
if (scr) CloseScreen (scr);
if (win) CloseWindow (win);
if (GfxBase) CloseLibrary (GfxBase);
if (IntuitionBase) CloseLibrary (IntuitionBase);
}
freelist()
{
register struct wlist *this = listbase, *tmp;
register int i;
while (this) {
for (i=0; i<DEPTH; i++)
if (this -> bitmap.Planes[i])
FreeRaster (this -> bitmap.Planes[i],
this -> sizx, this -> sizy);
tmp = this;
this = this -> prev;
free (tmp);
}
}
#asm
*\
* :ts=8 bk=0
* Un altro generatore di numeri casuali!!! By Leo Schwab
* Grazie a Sam Dicker per l'idea.
* Per assembler Metacomco
*
* Chiamata:
* long rnd (range);
* long range;
*
* Assemblaggio con Metacomco
* df1:c/assem rnd.s -o rnd.o
*
*/
blanks off
section code
xdef _rnd
_rnd lea rndseed,a0 ;Indirizzo deme
move.l 4(sp),d1 ;Gamma argomento
tst.l d1
ble.s setseed ;Seme di reset
move.l (a0),d0 ;Legge seme
ADD.L D0,D0
BHI.S over
EORI.L #$1D872B41,D0
over
move.l d0,(a0) ;Salva nuovo seme
andi.l #$ffff,d0 ;Forza in una word
andi.l #$ffff,d1
divu d1,d0 ;Divide per gamma
swap d0 ; resto (modulo)
ext.l d0
rts
setseed neg.l d1 ;Probabilmente non necessario
move.l d1,(a0)
rts
section data
rndseed dc.l 0
section code
#endasm